package com.binge.testThread;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class DuplicateClassFinder {

    public static void main(String[] args) {
        Map<String, ArrayList<String>> classLocations = new HashMap<>();

        try {
            processFile(Paths.get("/Users/bin/IdeaProjects/basic-management/target/basic-management.jar"), classLocations, "");
            printDuplicates(classLocations);
        } catch (IOException e) {
            System.err.println("Error processing file: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private static void processFile(Path filePath, Map<String, ArrayList<String>> classLocations, String parentPath) throws IOException {
        try (JarFile jarFile = new JarFile(filePath.toFile())) {
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                if (entry.getName().endsWith(".class")) {
                    String className = entry.getName().replace('/', '.').replace(".class", "");
                    String location = parentPath.isEmpty() ? filePath.toString() : parentPath + "!" + entry.getName();
                    classLocations.computeIfAbsent(className, k -> new ArrayList<>()).add(location);
                } else if (entry.isDirectory()) {
                    // Skip directories
                } else if (entry.getName().endsWith(".jar") || entry.getName().endsWith(".war")) {
                    // Processing nested JAR/WAR files
                    Path tempFile = Files.createTempFile("nested", ".jar");
                    try (InputStream is = jarFile.getInputStream(entry)) {
                        Files.copy(is, tempFile, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
                    } catch (IOException e) {
                        System.err.println("Failed to copy nested JAR: " + e.getMessage());
                        continue; // Skip this entry if copying failed
                    }

                    try {
                        String nestedJarPath = parentPath.isEmpty() ? filePath.toString() : parentPath + "!" + entry.getName();
                        processFile(tempFile, classLocations, nestedJarPath);
                    } finally {
                        Files.deleteIfExists(tempFile); // Ensure the temporary file is deleted
                    }
                }
            }
        }
    }
    private static void printDuplicates(Map<String, ArrayList<String>> classLocations) {
        int i = 0;
        boolean duplicatesFound = false;
        for (Map.Entry<String, ArrayList<String>> entry : classLocations.entrySet()) {
            if (entry.getValue().size() > 1) {
                i++;
                duplicatesFound = true;
                System.out.println("Duplicate class found: " + entry.getKey());
                System.out.println("Found in JARs/WARs:");
                entry.getValue().forEach(location -> System.out.println(" - " + location));
                System.out.println();
            }
        }

        System.out.println("Total duplicate classes found: " + i);
        if (!duplicatesFound) {
            System.out.println("No duplicate classes found.");
        }
    }

}